package com.hll.erp.controller;

import com.hll.erp.entity.ResultMap;
import com.hll.erp.entity.User;
import com.hll.erp.service.UserService;
import com.hll.erp.util.HashUtil;
import com.hll.erp.util.PropertiesUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * (User)表控制层
 *
 * @author makejava
 * @since 2021-07-04 15:18:01
 */
@RestController
@RequestMapping("user")
@Api(
    value = "用户controller",
    tags = {"用户操作接口"})
public class UserController {
  @Autowired PropertiesUtil propertiesUtil;
  @Autowired SessionDAO sessionDAO;
  @Autowired private UserService userService;

  @RequiresRoles("admin")
  @ApiOperation(value = "注册用户")
  @PostMapping("/register")
  public ResultMap register(
      @RequestParam(name = "用户名") String username, @RequestParam(name = "密码") String password) {
    ResultMap resultMap = new ResultMap();
    User user = userService.findUserByName(username);
    if (user != null) {
      resultMap.fail().code(203).message("用户名已存在");
    } else {
      user = new User();
      user.setUsername(username);
      user.setPassword(
          HashUtil.encode(
              propertiesUtil.getAlgorithm(), password, propertiesUtil.getHashIteration()));
      if (userService.save(user)) {
        resultMap.success().code(200).message("注册成功");
      } else {
        resultMap.fail().code(201).message("插入数据失败");
      }
    }
    return resultMap;
  }

  @ApiOperation(value = "用户登录")
  @PostMapping("/login")
  public ResultMap login(@RequestParam String username, @RequestParam String password) {
    ResultMap resultMap = new ResultMap();
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    try {
      subject.login(token);
      return resultMap.success().code(200).message(userService.findUserByName(username));
    } catch (UnknownAccountException accountException) {
      return resultMap.fail().code(205).message("用户不存在");
    } catch (IncorrectCredentialsException e) {
      return resultMap.fail().code(206).message("密码错误");
    }
  }

  @RequiresAuthentication
  @ApiOperation(value = "用户注销")
  @PostMapping("/logout")
  public ResultMap logout() {
    ResultMap resultMap = new ResultMap();
    Subject subject = SecurityUtils.getSubject();
    subject.logout();
    return resultMap.success().code(200).message("登出成功");
  }

  @RequiresAuthentication
  @ApiOperation(value = "用户修改密码")
  @PostMapping("/updateUserPassword")
  public ResultMap modifyPassword(
      @RequestParam String username,
      @RequestParam String password,
      @RequestParam String newPassword) {
    User user = userService.findUserByName(username);
    ResultMap resultMap = new ResultMap();
    if (null == user) {
      resultMap.fail().code(207).message("查无此人");
    } else {
      String passwordHash =
          HashUtil.encode(
              propertiesUtil.getAlgorithm(), password, propertiesUtil.getHashIteration());
      String newPasswordHash =
          HashUtil.encode(
              propertiesUtil.getAlgorithm(), newPassword, propertiesUtil.getHashIteration());
      if (user.getPassword().equals(passwordHash)) {
        user.setPassword(newPasswordHash);
        if (userService.updateById(user)) {
          resultMap.success().code(200).message(user);
        } else {
          resultMap.fail().code(201).message("插入数据失败");
        }
      } else {
        resultMap.fail().code(201).message("密码错误");
      }
    }
    return resultMap;
  }

  @RequiresRoles("admin")
  @ApiOperation(value = "重置用户密码")
  @PostMapping("/resetUserPassword")
  public ResultMap modifyPassword(@RequestParam Integer id, @RequestParam String password) {
    User user = userService.getById(id);
    ResultMap resultMap = new ResultMap();
    if (null == user) {
      resultMap.fail().code(207).message("查无此人");
    } else {
      user.setPassword(
          HashUtil.encode(
              propertiesUtil.getAlgorithm(), password, propertiesUtil.getHashIteration()));
      if (userService.updateById(user)) {
        resultMap.success().code(200).message(userService.getById(id));
      } else {
        resultMap.fail().code(201).message("插入数据失败");
      }
    }
    return resultMap;
  }

  @RequiresRoles("admin")
  @ApiOperation(value = "修改用户权限")
  @PostMapping("/updateUserRoles")
  public ResultMap updateRoles(@RequestBody User user) {
    ResultMap resultMap = new ResultMap();
    User old = userService.getById(user.getId());
    if (old != null) {
      user.setPassword(old.getPassword());
      user.setUsername(old.getUsername());
      if (userService.updateById(user)) {
        resultMap.success().code(200).message("更新成功");
      } else {
        resultMap.fail().code(201).message("插入数据失败");
      }
    } else {
      resultMap.fail().code(207).message("查无此人");
    }
    return resultMap;
  }

  @RequiresRoles("admin")
  @ApiOperation(value = "获取用户信息")
  @PostMapping("/getUsers")
  public ResultMap getUsers(
      @RequestParam(defaultValue = "1", value = "pageNo") Integer pageNo,
      @RequestParam(defaultValue = "5", value = "pageSize") Integer pageSize) {
    return new ResultMap().success().code(200).message(userService.getUsers(pageNo, pageSize));
  }

  @PostMapping("/getUserCount")
  public ResultMap getUserCount() {
    return new ResultMap().success().code(200).message(userService.count());
  }
}
